#pragma once

#include <httplib.h>
#include <spdlog/spdlog.h>
#include "../util/server.hh"
#include "../util/response.hh"
#include "../service/learn-service.hh"
#include "../util/except.hh"

namespace WordMemory
{
    class LearnController
    {
    public:
        static void registerBusiness()
        {
            Server::instance().regist<Server::BusType::GET>("/api/stats/learning", getLearningStats);
            Server::instance().regist<Server::BusType::GET>("/api/stats/daily-summary", getDailyLearningSummary);

            spdlog::info("Learn controller registered");
        }

    private:
        static void getLearningStats(const httplib::Request& req, httplib::Response& res)
        {
            try
            {
                if (!req.has_param("user_id")) {
                    throw ControllerExcept("user_id parameter is required");
                }
                int user_id = std::stoi(req.get_param_value("user_id"));
                Json::Value stats = LearnService::instance().getLearningStats(user_id);

                res.status = 200;
                res.set_content(ResponseMessage::success(stats), "application/json");
                spdlog::info("Fetched learning stats for user_id {}", user_id);
            }
            catch (const std::invalid_argument& e)
            {
                res.status = 400;
                res.set_content(ResponseMessage::error("Invalid user_id format: " + std::string(e.what())), "application/json");
                spdlog::error("Invalid user_id in getLearningStats: {}", req.get_param_value("user_id"));
            }
            catch (const ControllerExcept& e)
            {
                res.status = 400;
                res.set_content(ResponseMessage::error(e.what()), "application/json");
                spdlog::error("Controller error in getLearningStats: {}", e.what());
            }
            catch (const ServiceExcept& e) // Catching from service layer
            {
                res.status = 500; // Or a more specific error code based on e.what()
                res.set_content(ResponseMessage::error(e.what()), "application/json");
                spdlog::error("Service error in getLearningStats: {}", e.what());
            }
        }

        static void getDailyLearningSummary(const httplib::Request& req, httplib::Response& res)
        {
            try
            {
                if (!req.has_param("user_id")) {
                    throw ControllerExcept("user_id parameter is required");
                }
                int user_id = std::stoi(req.get_param_value("user_id"));

                int days = 30; // Default to 30 days
                if (req.has_param("days")) {
                    try {
                        days = std::stoi(req.get_param_value("days"));
                        if (days <= 0 || days > 90) { // Limit range for performance/sanity
                            days = 30;
                            spdlog::warn("Requested days out of range, defaulting to 30.");
                        }
                    }
                    catch (const std::invalid_argument&) {
                        spdlog::warn("Invalid days parameter, defaulting to 30.");
                        days = 30;
                    }
                }

                Json::Value summary_data = LearnService::instance().getDailyLearningSummary(user_id, days);

                res.status = 200;
                res.set_content(ResponseMessage::success(summary_data), "application/json");
                spdlog::info("Fetched daily learning summary for user_id {} (last {} days)", user_id, days);
            }
            catch (const std::invalid_argument& e)
            {
                res.status = 400;
                res.set_content(ResponseMessage::error("Invalid parameter format: " + std::string(e.what())), "application/json");
                spdlog::error("Invalid parameter in getDailyLearningSummary: {}", e.what());
            }
            catch (const ControllerExcept& e)
            {
                res.status = 400;
                res.set_content(ResponseMessage::error(e.what()), "application/json");
                spdlog::error("Controller error in getDailyLearningSummary: {}", e.what());
            }
            catch (const ServiceExcept& e)
            {
                res.status = 500;
                res.set_content(ResponseMessage::error(e.what()), "application/json");
                spdlog::error("Service error in getDailyLearningSummary: {}", e.what());
            }
        }
    };
}